home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Xconq 7.0d37 / source / x11 / xhelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-26  |  10.6 KB  |  382 lines  |  [TEXT/KAHL]

  1. /* Help for the X11 interface to Xconq.
  2.    Copyright (C) 1991, 1992, 1993, 1994, 1995 Stanley T. Shebs.
  3.  
  4. Xconq is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.  See the file COPYING.  */
  8.  
  9. #include "conq.h"
  10. #include "xconq.h"
  11.  
  12. /* (should go to ui.h?  and node stack code too?) */
  13. #define NODESTACKSIZE 100
  14.  
  15. static void describe_map PROTO ((int arg, char *key, char *buf));
  16.  
  17. static void help_next_callback PROTO ((Widget w, XtPointer client_data,
  18.                        XtPointer call_data));
  19. static void help_prev_callback PROTO ((Widget w, XtPointer client_data,
  20.                        XtPointer call_data));
  21. static void help_back_callback PROTO ((Widget w, XtPointer client_data,
  22.                        XtPointer call_data));
  23. static void help_close_callback PROTO ((Widget w, XtPointer client_data,
  24.                         XtPointer call_data));
  25. static void interp_help_command PROTO ((Side *side, int ch));
  26. static void update_help PROTO ((Side *side));
  27. static void jump_to_help_node PROTO ((Side *side, int i));
  28.  
  29. static void help_topic_callback PROTO ((Widget w, XtPointer dummy,
  30.                     XawListReturnStruct *list));
  31.  
  32. static char **nodetitles;
  33.  
  34. static void
  35. describe_map(arg, key, buf)
  36. int arg;
  37. char *key, *buf;
  38. {
  39.     strcat(buf, "In move mode:\n");
  40.     strcat(buf, "  The next unit that can do anything will be selected automatically.\n");
  41.     strcat(buf, "  Click on a destination to move the selected unit there.\n");
  42.     strcat(buf, "\n");
  43.     strcat(buf, "In look mode:\n");
  44.     strcat(buf, "  Click on a unit to make the current one.\n");
  45.     strcat(buf, "  To move it, use 'm'ove command or 'z' to switch back to survey mode.\n"); 
  46. }
  47.  
  48. static void 
  49. help_topic_callback (w, dummy, list)
  50. Widget w;
  51. XtPointer dummy;
  52. XawListReturnStruct *list;
  53. {
  54.   Side *side;
  55.   find_side_via_widget(w, &side);
  56.   jump_to_help_node(side, list->list_index);
  57. }
  58.  
  59. static void 
  60. jump_to_help_node(side, i)
  61. Side *side;
  62. int i;
  63. {
  64.   i = i % side->ui->nodenumber;
  65.   if (i<0)  i += side->ui->nodenumber;
  66.   XawListHighlight(side->ui->help_topicList, i);
  67.   side->ui->curhelpnode = side->ui->nodestack[i];
  68.   side->ui->nodestackpos = i;
  69.   update_help(side);
  70. }
  71.  
  72. void
  73. create_help(side)
  74. Side *side;
  75. {
  76.     int w, h, i;
  77.     Widget helppane;
  78.     HelpNode *hnp;
  79.  
  80.     add_help_node("map", describe_map, 0, firsthelpnode);
  81.  
  82.     /* initialize node stack */
  83.     if (side->ui->nodestack == NULL)
  84.       side->ui->nodestack =
  85.     (HelpNode **) xmalloc(NODESTACKSIZE * sizeof(HelpNode *));
  86.  
  87.     for (i=0, hnp=firsthelpnode;
  88.      hnp && (hnp!=firsthelpnode || i==0); hnp=hnp->next) {
  89.       side->ui->nodestack[i++] = hnp;
  90.     }
  91.     side->ui->nodenumber = i;
  92.  
  93.     nodetitles = (char **) xmalloc((side->ui->nodenumber+1)*sizeof(char *));
  94.     for (i=0; i<side->ui->nodenumber; i++) {
  95.       nodetitles[i] = side->ui->nodestack[i]->key;
  96.     }
  97.     nodetitles[side->ui->nodenumber] = NULL;
  98.  
  99. #if 0
  100.     /* useless with widgetified help, use resource file to change defaults */
  101.  
  102.     side->ui->helpw = 500;  side->ui->helph = 700;
  103.     if ( 0 /* !empty_string(geospec) */) {
  104.     /* This map has been given a preferred size - work to it. */
  105.     flags = XParseGeometry(geospec, &sx, &sy, &w, &h);
  106.     if (flags & WidthValue)
  107.       side->ui->helpw = w;
  108.     if (flags & HeightValue)
  109.       side->ui->helph = h;
  110.     /* Note that we allow the caller to specify geometries
  111.        that may be larger than the available screen, on the
  112.        theory that people specifying geometries explicitly
  113.        know what they're doing. */
  114.     } else {
  115.     /* Shrink to fit display if the default is too big. */
  116.     w = DisplayWidth(side->ui->dpy, side->ui->screen);
  117.     h = DisplayHeight(side->ui->dpy, side->ui->screen);
  118.     /* Leave a little room around the edges, but not too much;
  119.        Xconq help needs all the screen space it can get. */
  120.     side->ui->helpw = min(side->ui->helpw, w - w / 16);
  121.     side->ui->helph = min(side->ui->helph, h - h / 16);
  122.     }
  123. #endif
  124.  
  125.     side->ui->help_shell =
  126.       XtVaCreatePopupShell("helpShell", topLevelShellWidgetClass,
  127.                side->ui->shell,  NULL);
  128.     side->ui->help_form = 
  129.       XtVaCreateManagedWidget("form", formWidgetClass,
  130.                   side->ui->help_shell,  NULL);
  131.  
  132.     side->ui->help_title =
  133.       XtVaCreateManagedWidget("title", labelWidgetClass, side->ui->help_form,
  134.                   XtNlabel, "",
  135.                   XtNtop,    XawChainTop, 
  136.                   XtNbottom, XawChainTop, 
  137.                   XtNleft,   XawChainLeft, 
  138.                   XtNright,  XawChainRight, 
  139.                   NULL);
  140.  
  141.     side->ui->help_topicPort =
  142.       XtVaCreateManagedWidget("topicPort", viewportWidgetClass,
  143.                   side->ui->help_form,
  144.                   XtNallowVert, True,
  145.                   XtNfromVert, side->ui->help_title,
  146.                   XtNtop,    XawChainTop, 
  147.                   XtNbottom, XawChainBottom, 
  148.                   XtNleft,   XawChainLeft, 
  149.                   XtNright,  XawChainLeft, 
  150.                   NULL);
  151.  
  152.     side->ui->help_topicList =
  153.       XtVaCreateManagedWidget("topicList", listWidgetClass,
  154.                   side->ui->help_topicPort,
  155.                   XtNbottom, XawChainTop, 
  156.                   XtNverticalList, True,
  157.                   XtNforceColumns, True,
  158.                   XtNdefaultColumns, 1,
  159.                   NULL);
  160.     XawListChange(side->ui->help_topicList,
  161.           nodetitles, side->ui->nodenumber, 0, True);
  162.     XtAddCallback(side->ui->help_topicList, XtNcallback,
  163.           help_topic_callback, (XtPointer) NULL);
  164.  
  165.     side->ui->help_text =
  166.       XtVaCreateManagedWidget("text", asciiTextWidgetClass, side->ui->help_form,
  167.                   XtNdisplayCaret, False,
  168.                   XtNeditType, XawtextRead,
  169. /*                  XtNscrollHorizontal, XawtextScrollWhenNeeded, */
  170.                   XtNscrollVertical, XawtextScrollAlways,
  171.                   XtNwrap, XawtextWrapWord,
  172.                   XtNfromVert,  side->ui->help_title,
  173.                   XtNfromHoriz, side->ui->help_topicPort,
  174.                   XtNtop,    XawChainTop, 
  175.                   XtNbottom, XawChainBottom, 
  176.                   XtNleft,   XawChainLeft, 
  177.                   XtNright,  XawChainRight, 
  178.                   NULL);
  179.  
  180.     side->ui->help_next =
  181.       XtVaCreateManagedWidget("next", commandWidgetClass, side->ui->help_form,
  182.                   XtNlabel, "Next",
  183.                   XtNfromVert, side->ui->help_text,
  184.                   XtNtop,    XawChainBottom, 
  185.                   XtNbottom, XawChainBottom, 
  186.                   XtNleft,   XawChainLeft, 
  187.                   XtNright,  XawChainLeft, 
  188.                   NULL);
  189.     XtAddCallback(side->ui->help_next, XtNcallback, help_next_callback, NULL);
  190.     side->ui->help_prev =
  191.       XtVaCreateManagedWidget("prev", commandWidgetClass, side->ui->help_form,
  192.                   XtNlabel, "Prev",
  193.                   XtNfromHoriz, side->ui->help_next,
  194.                   XtNfromVert,  side->ui->help_text,
  195.                   XtNtop,    XawChainBottom, 
  196.                   XtNbottom, XawChainBottom, 
  197.                   XtNleft,   XawChainLeft, 
  198.                   XtNright,  XawChainLeft, 
  199.                   NULL);
  200.     XtAddCallback(side->ui->help_prev, XtNcallback, help_prev_callback, NULL);
  201.     side->ui->help_back =
  202.       XtVaCreateManagedWidget("back", commandWidgetClass, side->ui->help_form,
  203.                   XtNlabel, "Back",
  204.                   XtNfromHoriz, side->ui->help_prev,
  205.                   XtNfromVert,  side->ui->help_text,
  206.                   XtNtop,    XawChainBottom, 
  207.                   XtNbottom, XawChainBottom, 
  208.                   XtNleft,   XawChainLeft, 
  209.                   XtNright,  XawChainLeft, 
  210.                   NULL);
  211.     XtAddCallback(side->ui->help_back, XtNcallback, help_back_callback, NULL);
  212.     side->ui->help_close =
  213.       XtVaCreateManagedWidget("close", commandWidgetClass, side->ui->help_form,
  214.                   XtNlabel, "Close",
  215.                   XtNfromHoriz, side->ui->help_back,
  216.                   XtNfromVert,  side->ui->help_text,
  217.                   XtNtop,    XawChainBottom, 
  218.                   XtNbottom, XawChainBottom, 
  219.                   XtNleft,   XawChainLeft, 
  220.                   XtNright,  XawChainLeft, 
  221.                   NULL);
  222.     XtAddCallback(side->ui->help_close, XtNcallback, help_close_callback, NULL);
  223.  
  224.     XtRealizeWidget(side->ui->help_shell);
  225.  
  226.     /* which is the most useful help page to display at startup? */
  227.     jump_to_help_node (side, 2);
  228. }
  229.  
  230. static void 
  231. help_topics_callback(w, client_data, call_data)
  232. Widget w;
  233. XtPointer client_data;
  234. XtPointer call_data;
  235. {
  236.     Side *side;
  237.  
  238.     if (find_side_via_widget(w, &side)) {
  239.     interp_help_command(side, 't');
  240.     }
  241. }
  242.  
  243. static void 
  244. help_next_callback(w, client_data, call_data)
  245. Widget w;
  246. XtPointer client_data;
  247. XtPointer call_data;
  248. {
  249.     Side *side;
  250.  
  251.     if (find_side_via_widget(w, &side)) {
  252.     interp_help_command(side, 'n');
  253.     }
  254. }
  255.  
  256. static void 
  257. help_prev_callback(w, client_data, call_data)
  258. Widget w;
  259. XtPointer client_data;
  260. XtPointer call_data;
  261. {
  262.     Side *side;
  263.  
  264.     if (find_side_via_widget(w, &side)) {
  265.     interp_help_command(side, 'p');
  266.     }
  267. }
  268.  
  269. static void 
  270. help_back_callback(w, client_data, call_data)
  271. Widget w;
  272. XtPointer client_data;
  273. XtPointer call_data;
  274. {
  275.     Side *side;
  276.  
  277.     if (find_side_via_widget(w, &side)) {
  278.     interp_help_command(side, 'b');
  279.     }
  280. }
  281.  
  282. static void 
  283. help_close_callback(w, client_data, call_data)
  284. Widget w;
  285. XtPointer client_data;
  286. XtPointer call_data;
  287. {
  288.     Side *side;
  289.  
  290.     if (find_side_via_widget(w, &side)) {
  291.     popdown_help(side);
  292.     }
  293. }
  294.  
  295. /* Keyboard command interpretation for the help window. */
  296.  
  297. static void
  298. interp_help_command(side, ch)
  299. Side *side;
  300. int ch;
  301. {
  302.     int i;
  303.  
  304.     switch (ch) {
  305.       case 'n':
  306.         i = side->ui->nodestackpos+1;
  307.         break;
  308.       case 'p':
  309.         i = side->ui->nodestackpos-1;
  310.     break;
  311.       case 'b':
  312.     if (side->ui->nodestackpos <= 0) {
  313.         beep(side);
  314.         return;
  315.     }
  316.     i = side->ui->nodestackpos-1;
  317.     break;
  318.       case 't':
  319.     i = 0;
  320.     break;
  321.       default:
  322.     abort();  /* should never happen */
  323.     }
  324.  
  325.     jump_to_help_node(side, i);
  326. }
  327.  
  328. static void
  329. update_help(side)
  330. Side *side;
  331. {
  332.     char *keystr, *helpstr;
  333.  
  334.     if (!side->ui->help_shell)
  335.       return;
  336.     if (side->ui->curhelpnode == NULL)
  337.       return; /* (should never happen?) */
  338.  
  339.     /* Update the topic title widget. */
  340.     keystr = side->ui->curhelpnode->key;
  341.     if (keystr == NULL)
  342.       keystr = "???";
  343.     nargs = 0;
  344.     XtSetArg(tmpargs[nargs], XtNlabel, keystr);  nargs++;
  345.     XtSetValues(side->ui->help_title, tmpargs, nargs);
  346.  
  347.     /* Update the help info proper. */
  348.     helpstr = get_help_text(side->ui->curhelpnode);
  349.     if (helpstr == NULL)
  350.       helpstr = "???";
  351.     nargs = 0;
  352.     XtSetArg(tmpargs[nargs], XtNstring, helpstr);  nargs++;
  353.     XtSetArg(tmpargs[nargs], XtNlength, strlen(helpstr));  nargs++;
  354.     XtSetArg(tmpargs[nargs], XtNinsertPosition, 0);  nargs++;
  355.     XtSetValues(side->ui->help_text, tmpargs, nargs);
  356. }
  357.  
  358. void
  359. popup_help(side)
  360. Side *side;
  361. {
  362.     if (!side->ui->help_shell) {
  363.     create_help(side);
  364.     update_help(side);
  365.  
  366.     XSetWMProtocols(side->ui->dpy, XtWindow(side->ui->help_shell),
  367.             &side->ui->kill_atom, 1);
  368.     XtOverrideTranslations(side->ui->help_shell,
  369.         XtParseTranslationTable("<Message>WM_PROTOCOLS: wm-quit()"));
  370.     }
  371.     XtPopup(side->ui->help_shell, XtGrabNone);
  372.     /* Expose event will cause window contents to be drawn now. */
  373. }
  374.  
  375. void
  376. popdown_help(side)
  377. Side *side;
  378. {
  379.     if (side->ui->help_shell)
  380.       XtPopdown(side->ui->help_shell);
  381. }
  382.